/************************************************************************/
/* Name : Kiwon Yun
/* Partner's name : Eric Rooney
/* File Name : Betting.cpp
/* The name of assignment : Iteration 2
/************************************************************************/

#include "Betting.h"
#include <iostream>

using namespace std;

Betting::Betting(void)
{
	m_nMainPot = 0;
	m_nSidePot = 0;
	m_nLastBet =0;
	m_nCalls = 0;
	m_nRaises = 0;
	m_nFolds = 0;
	m_nAllInAmount = 99999;
	m_nAllIns = 0;
}

Betting::~Betting(void)
{
}

void Betting::Ante(Player* pPlayer)
{
	pPlayer->SetMoney(pPlayer->GetMoney()-1);
	m_nMainPot++;
}

void Betting::Raise(Player* pPlayer, int * m_nAmount)
{
	if((pPlayer->GetMoney()-(*m_nAmount+m_nLastBet))>=0)
	{
		pPlayer->SetMoney(pPlayer->GetMoney()-(*m_nAmount+m_nLastBet-pPlayer->GetBetSoFar()));
		m_nMainPot+=(*m_nAmount+m_nLastBet-pPlayer->GetBetSoFar());
		pPlayer->SetBetSoFar((*m_nAmount)+m_nLastBet);
		m_nLastBet+=(*m_nAmount);
		while(m_nMainPot>m_nAllInAmount)
		{
			m_nMainPot--;
			m_nSidePot++;
		}
		m_nCalls=0;
		m_nRaises++;
//		cout<<"So far you have bet: $"<<pPlayer->GetBetSoFar()<<endl;////////////////////////////////////////
		cout<<"Main pot $"<<m_nMainPot<<endl;//////////////////////////////////////////////
		cout<<"Side pot $"<<m_nSidePot<<endl;//////////////////////////////////////////////
	}
	else
	{
		if(*m_nAmount==99999)
			cout<<"Input out of range"<<endl;
		else
		{
//			cout<<"You cannot afford $"<<(*m_nAmount)+m_nLastBet<<" to raise this amount"<<endl;
//			cout << "You have just $" << pPlayer->GetMoney() << " now." << endl;
			*m_nAmount=99999;
		}
	}

	assert(m_nLastBet>=0);
	assert(m_nMainPot>=0);
	assert(m_nAllInAmount>=0);
	assert(m_nSidePot>=0);
}



void Betting::Call(Player* pPlayer, int m_nPlayersNum)
{
	if((pPlayer->GetMoney()-m_nLastBet+pPlayer->GetBetSoFar())>=0)
	{
		pPlayer->SetMoney(pPlayer->GetMoney()-m_nLastBet+pPlayer->GetBetSoFar());
		if(m_nLastBet-pPlayer->GetBetSoFar()>0)
			m_nMainPot+=(m_nLastBet-pPlayer->GetBetSoFar());
		pPlayer->SetBetSoFar(m_nLastBet);
		while(m_nMainPot>m_nAllInAmount)
		{
			m_nMainPot--;
			m_nSidePot++;
		}
//				cout<<"So far you have bet: $"<<pPlayer->GetBetSoFar()<<endl;////////////////////////////////////////
				cout<<"Main pot $"<<m_nMainPot<<endl;//////////////////////////////////////////////
		cout<<"Side pot $"<<m_nSidePot<<endl;//////////////////////////////////////////////
	}
	else
	{
		if(pPlayer->GetAllIn()==false)
		{
	    cout<<"You have gone all in."<<endl;
	    m_nMainPot+=(pPlayer->GetMoney());
		pPlayer->SetAllInAmount(pPlayer->GetMoney()+pPlayer->GetBetSoFar());
		pPlayer->SetBetSoFar(pPlayer->GetBetSoFar()+pPlayer->GetMoney());
		m_nAllInAmount=((pPlayer->GetMoney()+pPlayer->GetBetSoFar())*m_nPlayersNum);
		while(m_nMainPot>m_nAllInAmount)
		{
			m_nMainPot--;
			m_nSidePot++;
		}
	    pPlayer->SetMoney(0);
		pPlayer->SetAllIn(true);
		}
				cout<<"Main pot $"<<m_nMainPot<<endl;//////////////////////////////////////////////
		cout<<"Side pot $"<<m_nSidePot<<endl;//////////////////////////////////////////////
//		cout<<"Player's all in amount $"<<pPlayer->GetAllInAmount()<<endl;/////////////////////////////////////////////
//		cout<<"Main pot's all in amount $"<<m_nAllInAmount<<endl;/////////////////////////////////////////////
    }
	m_nCalls++;
	if(GetAllIns()>1)
		cout<<"Warning: there has been more than one all in!"<<endl;

	assert(m_nLastBet>=0);
	assert(m_nMainPot>=0);
	assert(m_nSidePot>=0);
	assert(m_nAllInAmount>=0);
}

//fold function:voluntarily losing for the round forfeiting cards and money placed into pot.
void Betting::Fold(Player* pPlayer)
{
	 pPlayer->SetFold(true);
	 m_nFolds++;
}

int Betting::GetCalls()
{
	return m_nCalls;
}

int Betting::GetRaises()
{
	return m_nRaises;
}

int Betting::GetFolds()
{
	return m_nFolds;
}

void Betting::ResetRaises()
{
	m_nRaises=0;
}

void Betting::ResetCalls()
{
	m_nCalls=0;
}

void Betting::ResetLastBet()
{
	m_nLastBet=0;
}

void Betting::ResetFolds()
{
	m_nFolds=0;
}

int Betting::GetLastBet()
{
	return m_nLastBet;
}

void Betting::DistributeMoney(Player* pWinner, Player* pSecondWinner)
{
	assert(pWinner);

	while(m_nMainPot>0)
	{
		m_nMainPot--;
		pWinner->SetMoney(pWinner->GetMoney()+1);
	}

	// if winner is all-in player, the second winner get the money on the side-pot.
	if(pWinner->GetAllIn()==false)
	{
		while(m_nSidePot>0)
		{
			m_nSidePot--;
			pWinner->SetMoney(pWinner->GetMoney()+1);
		}
	}
	else
	{
		while(m_nSidePot>0)
		{
			assert(pSecondWinner);
			m_nSidePot--;
			pSecondWinner->SetMoney(pWinner->GetMoney()+1);
		}
	}

	assert(m_nMainPot>=0);
	assert(m_nSidePot>=0);
}

void Betting::TieDistributeMoney(Player* pWinner, int nTiedWinnerNum)
{
	if(pWinner->GetAllIn()==false)
	{
		while((m_nMainPot/nTiedWinnerNum)>=1)
		{
			m_nMainPot--;
			pWinner->SetMoney(pWinner->GetMoney()+1);
		}
		while((m_nSidePot/nTiedWinnerNum)>=1)
		{
			m_nSidePot--;
			pWinner->SetMoney(pWinner->GetMoney()+1);
		}
	}
	else
	{
		while(m_nMainPot>0)
		{
			m_nMainPot--;
			pWinner->SetMoney(pWinner->GetMoney()+1);
		}
	}
	assert(m_nMainPot>=0);
	assert(m_nSidePot>=0);
}


void Betting::ResetAllIns()
{
	m_nAllIns=0;
}

int Betting::GetAllIns()
{
	return m_nAllIns;
}

void Betting::SetAllIns(int a_nAllIns)
{
	m_nAllIns=a_nAllIns;
}

void Betting::ResetAllInAmount()
{
	m_nAllInAmount=99999;
}
void Betting::ResetAllData()
{
	ResetRaises();
	ResetCalls();
	ResetLastBet();
	ResetAllIns();
	ResetFolds();
	ResetAllInAmount();
}
